/**
 * @author qiuny
 * @description 复制插件
 * @class
 * @see {@link CoverEditor}
 */

import { fabric } from "fabric";
import { v4 as uuidV4 } from 'uuid';
import DOMPurify from 'dompurify'

class CopyPlugin {
    static apis = ['clone']
    constructor(canvas, editor) {
        this.canvas = canvas
        this.editor = editor
        this.hotkeys = ["ctrl+c", 'ctrl+v']
        this.cache = null
        // 设置偏移距离，官方案例也是10
        this.offsetDistance = 10
        this.init()
    }

    destroy() {
        console.log('CopyPluginDestroy');
        window.removeEventListener('paste', (e) => this.pasteListener(e));
    }

    // 初始化监听web浏览器粘贴事件
    init() {
        // console.log('CopyPluginInit');
        window.addEventListener('paste', e => this.pasteListener)
    }

    async pasteListener(event) {
        const canvas = this.canvas;
        if (document.activeElement === document.body) {
            event.preventDefault(); // 阻止默认粘贴行为
        } else {
            return;
        }
    }

    // 多个对象也是被包裹成一个对象的，在_object属性能查看到
    _pasteMultipleActiveObject(activeObject) {
        const canvas = this.canvas
        activeObject?.clone(clonedMulObject => {
            canvas.discardActiveObject()
            if (clonedMulObject.left === void 0 || clonedMulObject.top === void 0) return
            // 将克隆画布重新赋值
            clonedMulObject.canvas = canvas
            clonedMulObject.set({
                left: clonedMulObject.left + this.offsetDistance,
                top: clonedMulObject.top + this.offsetDistance,
                evented: true,
                id: uuidV4()
            })
            // 循环内部子元素
            clonedMulObject.forEachObject(item => {
                item.id = uuidV4()
                canvas.add(item)
            })
            // 解决不可选择问题
            clonedMulObject.setCoords()
            canvas.setActiveObject(clonedMulObject)
            canvas.requestRenderAll()
        })
    }

    _pasteSingleActiveObject(activeObject) {
        const canvas = this.canvas
        activeObject?.clone(cloned => {
            if (cloned.left === void 0 || cloned.top === void 0) return
            // 取消已选择
            canvas.discardActiveObject()
            cloned.set({
                left: cloned.left + this.offsetDistance,
                top: cloned.top + this.offsetDistance,
                evented: true,
                id: uuidV4()
            })
            canvas.add(cloned)
            canvas.setActiveObject(cloned)
            canvas.requestRenderAll()
        })
    }

    _pasteCleanText(text = "") {
        const canvas = this.canvas
        if (typeof text === 'string') {
            const activeObject = this.canvas.getActiveObject()
            if (
                activeObject &&
                (activeObject.type === 'textbox' || activeObject.type === 'i-text') &&
                activeObject.text
            ) {
                const cursorPosition = activeObject.selectionStart;
                const textBeforeCursorPosition = activeObject.text.substring(0, cursorPosition);
                const textAfterCursorPosition = activeObject.text.substring(cursorPosition);

                // 更新文本对象的文本
                activeObject.set('text', textBeforeCursorPosition + text + textAfterCursorPosition);

                // 重新设置光标的位置
                activeObject.selectionStart = cursorPosition + text.length;
                activeObject.selectionEnd = cursorPosition + text.length;

                // 重新渲染画布展示更新后的文本
                activeObject.dirty = true;
                canvas.renderAll();
            } else {
                const fabricText = new fabric.IText(text, {
                    left: 100,
                    top: 100,
                    fontSize: 30,
                    id: uuidV4(),
                });
                canvas.add(fabricText);
                canvas.setActiveObject(fabricText);
            }
        }
    }

    // 克隆元素
    clone(fabricActiveObject) {
        const activeObject = fabricActiveObject || this.canvas.getActiveObject()
        if (!activeObject) return
        if (activeObject.type === 'activeSelection') {
            // 复制多个对象
            this._pasteMultipleActiveObject(activeObject)
        } else {
            // 复制单个对象
            this._pasteSingleActiveObject(activeObject)
        }
    }

    // 快捷键扩展回调
    hotkeyEvent(eventName, evt) {
        if (eventName === 'ctrl+c' && evt.type === 'keydown') {
            const activeObject = this.canvas.getActiveObject();
            this.cache = activeObject;
        }
        if (eventName === 'ctrl+v' && evt.type === 'keydown') {
            if (this.cache) {
                this.clone(this.cache);
            } else {
                // 没有选择fabric的元素，可以粘贴其他文本，比如纯文本
                // 读取剪贴板内容
                navigator.clipboard.readText().then(res => {
                    // 过滤文本恶意内容，防止xss攻击
                    const cleanText = DOMPurify.sanitize(res)
                    this._pasteCleanText(cleanText.trim())
                }).catch(err => {
                    console.log(err);
                })
            }
        }
    }

    destroy() {
        console.log('CopyPlugin destroy');
    }
}

export default CopyPlugin;